package response

import (
	"net/http"

	errcodeEnum "yunj/pkg/yunj/core/enum/errcode"

	jsoniter "github.com/json-iterator/go"

	"github.com/gin-gonic/gin"
)

type JsonData struct {
	Errcode int    `json:"errcode"`
	Msg     string `json:"msg"`
	Data    any    `json:"data"`
}

// 响应json数据
func (j *JsonData) Response(ctx *gin.Context) {
	if j.Msg == "" {
		// 获取错误码对应消息
		if errcodeValue, ok := errcodeEnum.IsValue(j.Errcode); ok {
			if msg := errcodeEnum.ByValue(errcodeValue).GetMsg(); msg != "" {
				j.Msg = msg
			}
		}
	}
	// ctx.JSON(http.StatusOK, j)

	json := jsoniter.ConfigCompatibleWithStandardLibrary
	jsonData, err := json.Marshal(j)
	if err != nil {
		failJsonData := FailJsonData("响应异常！json序列化数据失败：" + err.Error())
		ctx.JSON(http.StatusOK, failJsonData)
		return
	}
	ctx.Data(http.StatusOK, "application/json; charset=utf-8", jsonData)
}

// 响应json数据并终止当前请求执行
func (j *JsonData) AbortResponse(ctx *gin.Context) {
	j.Response(ctx)
	ctx.Abort()
}

// 成功的json数据
func SuccessJsonData(data any, msg ...string) *JsonData {
	message := ""
	if len(msg) > 0 {
		message = msg[0]
	}
	return &JsonData{
		Errcode: errcodeEnum.SUCCESS,
		Msg:     message,
		Data:    data,
	}
}

// 响应成功的json数据
func Success(ctx *gin.Context, data any, msg ...string) {
	SuccessJsonData(data, msg...).Response(ctx)
}

// 成功的空json数据
func SuccessEmptyJsonData() *JsonData {
	return &JsonData{
		Errcode: errcodeEnum.SUCCESS,
	}
}

// 失败的json数据
func FailJsonData(msg string, errcode ...int) *JsonData {
	errcodeVal := errcodeEnum.ERROR
	if len(errcode) > 0 {
		errcodeVal = errcode[0]
	}
	return &JsonData{
		Errcode: errcodeVal,
		Msg:     msg,
	}
}

// 响应失败的json数据
func Fail(ctx *gin.Context, msg string, errcode ...int) {
	FailJsonData(msg, errcode...).Response(ctx)
}

// 失败错误码的json数据
func FailErrcodeJsonData(errcode int) *JsonData {
	return &JsonData{
		Errcode: errcode,
	}
}

// 响应失败错误码的json数据
func FailErrcode(ctx *gin.Context, errcode int) {
	FailErrcodeJsonData(errcode).Response(ctx)
}

// 响应成功的json数据并终止当前请求执行
func AbortSuccess(ctx *gin.Context, data any, msg ...string) {
	SuccessJsonData(data, msg...).AbortResponse(ctx)
}

// 响应失败的json数据并终止当前请求执行
func AbortFail(ctx *gin.Context, msg string, errcode ...int) {
	FailJsonData(msg, errcode...).AbortResponse(ctx)
}
